package com.pic.mgt.syushin.executer;

import java.io.File;

import org.springframework.dao.DataAccessException;

import com.pic.mgt.IgxStatus;
import com.pic.mgt.dao.IBusinessMgtDao;
import com.pic.mgt.executer.TargetAction;
import com.pic.mgt.executer.TargetFileProcessException;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.manager.business.BasicBusinessInfoBean;
import com.pic.mgt.manager.business.BusinessManager;
import com.pic.mgt.unit.Business;
import com.pic.mgt.unit.operation.BusinessUnitOperation;
import com.pic.mgt.unit.operation.UnitOperationException;

public final class BatchSyushinTargetFileProcess implements TargetAction {
	private String syushinBucketTmpPathStr;
	private BusinessUnitOperation simpleBusinessUnitOperation;
	private IBusinessMgtDao businessMgtDao;
	private BusinessManager businessManager;
	
	private Business business;

	@Override
	public void perform(Business business) throws TargetFileProcessException {
		this.business = business;
		
		File syushinBusinessBucketTmpPath = new File(syushinBucketTmpPathStr,
													 business.getBusinessName());
		try {
			/*
			 * 同歩的目的是要避免在list要打包的檔案清單同時,SyushinBatchBusinessUnitExecuter
			 * 又將檔案移入此暫存目錄中。
			 */
			BasicBusinessInfoBean basicBusinessInfoBean =
						businessManager.getBasicBusinessInfoBean(business.getBusinessName());
			synchronized (basicBusinessInfoBean.getBusinessName()) {
				// ********************** Log **********************
				if (IgxLog.messageDetailsLog.isInfoMode()) {
					IgxLog.messageDetailsLog.info(this,
							"Shifting target file '{}' to syushin bucket tmp.",
							business.getTargetFilename());
				}
				// ********************** Log **********************
				
				// 搬移目標檔案
				simpleBusinessUnitOperation.moveTargetFile(business, syushinBusinessBucketTmpPath);
				
				// ********************** Log **********************
				if (IgxLog.messageDetailsLog.isInfoMode()) {
					IgxLog.messageDetailsLog.info(this,
							"Shifting target file '{}' to syushin bucket tmp completed.",
							business.getTargetFilename());
				}
				// ********************** Log **********************
				
				// 更新 DB 狀態
				// throws DataAccessException
				updateStatusByUnitName(IgxStatus.BUSINESS_BATCH_TMP);
				
				// ********************** Log **********************
				if (IgxLog.messageLog.isTraceMode()) {
					IgxLog.messageLog.trace(this,
							"Update status to db table '{}' for unit '{}' completed.",
							this.businessMgtDao.getTableName(),
							business.getUnitName());
				}
				// ********************** Log **********************
			}
		} catch (UnitOperationException e1) {
			throw new TargetFileProcessException(
					"Shifting target file '" + business.getTargetFilename() + 
					"' to syushin bucket tmp failed.", e1);
		} catch (DataAccessException e2) {
			throw new TargetFileProcessException(
					"Update status to db table '" + this.businessMgtDao.getTableName() + 
					"' for unit '" + this.business.getUnitName() + "' failed.", e2);
		}
	}
	
	private void updateStatusByUnitName(String statusValue) throws DataAccessException {
		// throws DataAccessException
		this.businessMgtDao.updateStatusByUnitName(
							statusValue, business.getUnitName());
	}
	
	// --- getter and setter ---

	public void setSyushinBucketTmpPathStr(String syushinBucketTmpPathStr) {
		this.syushinBucketTmpPathStr = syushinBucketTmpPathStr;
	}

	public void setSimpleBusinessUnitOperation(
			BusinessUnitOperation simpleBusinessUnitOperation) {
		this.simpleBusinessUnitOperation = simpleBusinessUnitOperation;
	}

	public void setBusinessMgtDao(IBusinessMgtDao businessMgtDao) {
		this.businessMgtDao = businessMgtDao;
	}

	public void setBusinessManager(BusinessManager businessManager) {
		this.businessManager = businessManager;
	}
	
}
